package com.mw.mwreaderdemo;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.mwcard.Reader;
import com.mwcard.ReaderAndroidBLE;
import com.mwcard.ReaderAndroidBlueTooth;
import com.mwcard.ReaderAndroidCom;
import com.mwcard.ReaderAndroidUsb;

import java.util.HashMap;
import java.util.Iterator;

import pub.devrel.easypermissions.EasyPermissions;

public class MainActivity extends Activity {

    private Button btnOpenReader;
    private Button btnCloseReader;
    private Button btnCardOperat;
    private Button btnReaderBeep;
    private Button btnCheckCard;
    private RadioButton rbBluetooth;
    private RadioButton rbBLEBluetooth;
    private RadioGroup rgBluetooth;
    private LinearLayout layoutBtName;
    private EditText etBluetoothName;
    private EditText etOffset;
    private EditText etLen;
    private EditText result;
    private Spinner spCommunicationMethod;
    private Spinner spSerialPort;
    private Button btnReadRemarks;
    private Button btnWriteRemarks;
    private EditText etRemarks;

    /**
     * 进度条
     */
    ProgressDialog pb;
    /**
     * 蓝牙适配器
     */
    BluetoothAdapter mBluetoothAdapter;
    /**
     * 蓝牙设备
     */
    private BluetoothDevice bluetoothDevices;
    /**
     * USB设备
     */
    private String Device_USB = "com.android.example.USB";
    /**
     * usb管理器
     */
    private UsbManager manager;

    //  上一次点击的时间 long型  
    private long beforeClick = 0;

    public final static String SER_KEY = "com.mw.mwreaderdemo.MainActivity";
    /*
     * 读写器通信类型. 0--USB; 1--普通蓝牙; 2--BLE蓝牙; 3--串口
     */
    private int readerType = 0;
    private boolean isHaveDevice = false;
    private String deviceNameStr = "MWLink-R6-BLE";  //连接蓝牙设备名字，必须与搜索名一致，很关键
    private String TAG = MainActivity.class.getSimpleName();
    private static final int REQUEST_CODE_ACCESS_5_Down = 1;
    private static final int REQUEST_CODE_ACCESS_6 = 2;
    private static final int REQUEST_CODE_LOCATION = 3;
    private boolean permissions = true;
    private Object mLockStatus = new Object(); // 状态锁
    /**
     * Stops scanning after 10 seconds.
     */
    private static final long SCAN_PERIOD = 5000;

    public static ReaderAndroidUsb readerAndroidUsb = null;
    public static Reader reader = null;
    private boolean isScan = false;
    private Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        if (EasyPermissions.hasPermissions(
                this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION
        )) {
        } else {
            EasyPermissions.requestPermissions(
                    this,
                    "因功能需要，请同意如下权限",
                    0,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION
            );
        }
        btnOpenReader = (Button) findViewById(R.id.btnOpenReader);
        btnCloseReader = (Button) findViewById(R.id.btnCloseReader);
        btnCardOperat = (Button) findViewById(R.id.btnCardOperat);
        btnCheckCard = (Button) findViewById(R.id.btnCheckCard);
        etBluetoothName = (EditText) findViewById(R.id.etBluetoothName);
        layoutBtName = (LinearLayout) findViewById(R.id.layoutBtName);
        rgBluetooth = (RadioGroup) findViewById(R.id.rgBluetooth);
        rbBluetooth = (RadioButton) findViewById(R.id.rbBluetooth);
        rbBLEBluetooth = (RadioButton) findViewById(R.id.rbBLEBluetooth);
        result = (EditText) findViewById(R.id.result);
        spCommunicationMethod = (Spinner) findViewById(R.id.spCommunicationMethod);
        spSerialPort = (Spinner) findViewById(R.id.spSerialPort);
        btnReaderBeep = (Button) findViewById(R.id.btnReaderBeep);
        etOffset = (EditText) findViewById(R.id.etOffset);
        etLen = (EditText) findViewById(R.id.etLen);
        etRemarks = (EditText) findViewById(R.id.etRemarks);
        btnReadRemarks = (Button) findViewById(R.id.btnReadRemarks);
        btnWriteRemarks = (Button) findViewById(R.id.btnWriteRemarks);

        btnOpenReader.setOnClickListener(new btnOpenReaderClick());

        btnCloseReader.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                try {
                    int st = 0;
                    st = reader.closeReader();
                    beforeClick = System.currentTimeMillis();
                    if (st == 0) {
                        etResultAddStr("设备已断开连接");
                        reader = null;
                    } else {
                        etResultAddStr("设备断开连接失败");
                    }
                } catch (Exception e) {
                    etResultAddStr(e.getMessage());
                }
                spCommunicationMethod.setEnabled(true);
                rbBluetooth.setEnabled(true);
                rbBLEBluetooth.setEnabled(true);
                etBluetoothName.setEnabled(true);
            }
        });

        //卡片操作
        btnCardOperat.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub

                Builder builder = new Builder(MainActivity.this);
                builder.setTitle("请选择要操作的卡片类型");
                builder.setItems(new String[]{"CPU卡", "S50/S70", "SLE4442/4428", "AT88SC102", "AT88SC153", "AT88SC1604", "磁条卡", "NT3H1101/NT3H1201", "AT24CXX", "二维码", "电子健康卡"},
                        new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                // TODO Auto-generated method stub
                                Intent newIntent = null;
                                switch (which) {
                                    case 0:
                                        newIntent = new Intent(MainActivity.this, Cpu.class);
                                        break;
                                    case 1:
                                        newIntent = new Intent(MainActivity.this, S50_70.class);
                                        break;
                                    case 2:
                                        newIntent = new Intent(MainActivity.this, SLE42_28.class);
                                        break;
                                    case 3:
                                        newIntent = new Intent(MainActivity.this, AT102.class);
                                        break;
                                    case 4:
                                        newIntent = new Intent(MainActivity.this, AT153.class);
                                        break;
                                    case 5:
                                        newIntent = new Intent(MainActivity.this, AT1604.class);
                                        break;
                                    case 6:
                                        newIntent = new Intent(MainActivity.this, MagcardActivity.class);
                                        break;
                                    case 7:
                                        newIntent = new Intent(MainActivity.this, NT3H1101.class);
                                        break;
                                    case 8:
                                        newIntent = new Intent(MainActivity.this, AT24C.class);
                                        break;
                                    case 9:
                                        newIntent = new Intent(MainActivity.this, QRCodeActivity.class);
                                        break;
                                    case 10:
                                        newIntent = new Intent(MainActivity.this, EHealthCard.class);
                                        break;
                                }
                                startActivity(newIntent);
                            }
                        });
                builder.create();
                builder.show();
            }
        });

        //自动测卡
        btnCheckCard.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                try {
                    int cardType = reader.CheckCard();
                    String str;
                    switch (cardType) {
                        case 1:
                            str = "AT24C01A";
                            break;
                        case 2:
                            str = "AT24C02";
                            break;
                        case 3:
                            str = "AT24C04";
                            break;
                        case 4:
                            str = "AT24C08";
                            break;
                        case 5:
                            str = "AT24C16";
                            break;
                        case 11:
                            str = "AT24C32";
                            break;
                        case 6:
                            str = "AT24C64";
                            break;
                        case 7:
                            str = "AT24C128";
                            break;
                        case 8:
                            str = "AT24C256";
                            break;
                        case 21:
                            str = "SLE4442";
                            break;
                        case 31:
                            str = "SLE4428";
                            break;
                        case 51:
                            str = "AT88SC102";
                            break;
                        case 54:
                            str = "AT88SC153";
                            break;
                        case 52:
                            str = "AT88SC1604";
                            break;
                        case 13:
                            str = "AT88SC1608";
                            break;
                        case 255:
                            str = "CPU";
                            break;
                        default:
                            str = "未知卡型";
                            break;
                    }
                    etResultAddStr("卡型：" + str);
                } catch (Exception e) {
                    etResultAddStr(e.getMessage());
                }
            }
        });

        etBluetoothName.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                // TODO Auto-generated method stub
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                // TODO Auto-generated method stub
            }

            @Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub
                deviceNameStr = s.toString();
            }
        });

        //普通蓝牙
        rbBluetooth.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
                // TODO Auto-generated method stub
                if (arg1) {
                    readerType = 1;
                    etBluetoothName.setText("M&W BlueTooth");
                }
            }
        });

        //低功耗蓝牙
        rbBLEBluetooth.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
                // TODO Auto-generated method stub
                if (arg1) {
                    readerType = 2;
                    etBluetoothName.setText("MWlink-C5-BLE");
                }
            }
        });

        // 设置双击操作信息提示框清除数据
        result.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View arg0, MotionEvent event) {
                // TODO Auto-generated method stub
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    if (System.currentTimeMillis() - beforeClick > 500) {
                        beforeClick = System.currentTimeMillis();
                    } else {
                        result.setText("");
                    }
                }
                return false;
            }
        });

        spCommunicationMethod.setOnItemSelectedListener(new OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                // TODO Auto-generated method stub
                if (arg2 == 0) {
                    rbBLEBluetooth.setChecked(false);
                    rbBluetooth.setChecked(false);
                    rgBluetooth.setVisibility(View.GONE);
                    layoutBtName.setVisibility(View.GONE);
                    spSerialPort.setVisibility(View.INVISIBLE);
                    readerType = 0;

                } else if (arg2 == 1) {
                    rgBluetooth.setVisibility(View.VISIBLE);
                    layoutBtName.setVisibility(View.VISIBLE);
                    // 多次设置rbBluetooth的选中状态，才能在UI中正确显示rbBLEBluetooth的状态
                    rbBluetooth.setChecked(false);
                    rbBluetooth.setChecked(true);
                    rbBluetooth.setChecked(false);
                    rbBLEBluetooth.setChecked(true);
                    spSerialPort.setVisibility(View.INVISIBLE);
                } else if (arg2 == 2) {
                    rbBLEBluetooth.setChecked(false);
                    rbBluetooth.setChecked(false);
                    rgBluetooth.setVisibility(View.GONE);
                    layoutBtName.setVisibility(View.GONE);
                    spSerialPort.setVisibility(View.VISIBLE);
                    readerType = 3;
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
                // TODO Auto-generated method stub

            }
        });

        //鸣响
        btnReaderBeep.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                try {
                    if (MainActivity.reader == null) {
                        Toast.makeText(MainActivity.this, "设备未打开", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    //int i= 0;
                    //while(true)
                    //{
                    //	if(i<100)
                    //	{
                    reader.beep(1, 1, 2);
                    //		etResultAddStr("鸣响成功！ "+i);
                    //	}
                    //	else
                    //	{
                    //		break;
                    //	}
                    //	i++;
                    //}
                    //etResultAddStr("鸣响成功！");
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    etResultAddStr(e.getMessage());
                }
            }
        });

        // 将输入字符转换为大写
        etRemarks.setTransformationMethod(new InputLowerToUpper());
        // 设置数据长度编辑框中的数据根据输入数据的长度而改变
        etRemarks.addTextChangedListener(new TextWatcher() {

            @Override
            // 在原有的文本s中，从start开始的count个字符替换长度为before的旧文本
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                // TODO Auto-generated method stub

            }

            @Override
            // 原有的文本s中，从start开始的count个字符将会被一个新的长度为after的文本替换
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                // TODO Auto-generated method stub

            }

            @Override
            public void afterTextChanged(Editable arg0) {
                // TODO Auto-generated method stub
                etLen.setText(arg0.toString().length() + "");
            }
        });

        btnReadRemarks.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                if (MainActivity.reader == null) {
                    Toast.makeText(MainActivity.this, "设备未打开", Toast.LENGTH_SHORT).show();
                    return;
                }
                int offset = Integer.parseInt(etOffset.getText().toString());
                int len = Integer.parseInt(etLen.getText().toString());
                try {
                    etResultAddStr(reader.readConfig(offset, len));
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    etResultAddStr(e.getMessage());
                }
            }
        });

        btnWriteRemarks.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                if (MainActivity.reader == null) {
                    Toast.makeText(MainActivity.this, "设备未打开", Toast.LENGTH_SHORT).show();
                    return;
                }
                try {
                    int offset = Integer.parseInt(etOffset.getText().toString());
                    // int len = Integer.parseInt(etLen.getText().toString());
                    String hexStr = etRemarks.getText().toString();
                    reader.writeConfig(offset, hexStr);
                    etResultAddStr("写备注区成功!");
                } catch (Exception e) {
                    // TODO: handle exception
                    etResultAddStr(e.getMessage());
                }
            }
        });

        spCommunicationMethod.setSelection(0, true);
        deviceNameStr = etBluetoothName.getText().toString();
        pb = new ProgressDialog(MainActivity.this);
        mHandler = new Handler();

        /*
         * 在使用USB读写器设备前，应用必须获得权限。
         * 为了确切地获得权限，首先需要创建一个广播接收器。在调用requestPermission()这个方法时从得到的广播中监听这个意图。
         * 通过调用requestPermission()这个方法为用户跳出一个是否连接该设备的对话框。
         */
        IntentFilter filter = new IntentFilter(Device_USB);
        filter.addAction(BluetoothDevice.ACTION_FOUND);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

        /*
         * 注册广播接收器.
         * 通过filter实例告诉ActivityManagerService,订阅的广播是Device_USB/ACTION_FOUND 类型的
         * ActivityManagerService在收到Device_USB/ACTION_FOUND类型的广播时，
         * 就会分发给mUsbReceiver实例的onReceive函数。
         */
        this.registerReceiver(this.mUsbReceiver, filter);
    }

    /* 创建广播接收器 **/
    private BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        public void onReceive(Context paramAnonymousContext, Intent paramAnonymousIntent) {
            String action = paramAnonymousIntent.getAction();
            // 判断广播类型
            if (Device_USB.equals(action)) {
                // USB设备
                try {
                    UsbDevice device = (UsbDevice) paramAnonymousIntent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    // 如果用户同意，则对读写器进行操作
                    if (paramAnonymousIntent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        readerAndroidUsb = new ReaderAndroidUsb(manager);
                        try {
                            // 连接读写器
                            int st = readerAndroidUsb.openReader(device);
                            if (st >= 0) {
                                reader = readerAndroidUsb;
                                etResultAddStr("读写器连接成功");
                                ReaderOperation();
                            } else {
                                etResultAddStr("读写器连接失败");
                            }
                        } catch (Exception e) {
                            // TODO: handle exception
                        }
                    }
                } finally {
                }
            } else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                // 发现蓝牙设备时
                // 从Intent中获取设备对象
                bluetoothDevices = paramAnonymousIntent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                Log.w(TAG, bluetoothDevices.getName() + ":" + bluetoothDevices.getAddress());
                if (bluetoothDevices.getName() != null) {
                    if (bluetoothDevices.getName().equals(deviceNameStr)) {
                        isHaveDevice = true;
                        mBluetoothAdapter.cancelDiscovery();
                    }
                }
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                if (isHaveDevice) {
                    etResultAddStr(">>>扫描到设备: \n" + bluetoothDevices.getName() + ":" + bluetoothDevices.getAddress());
                    try {
                        ReaderAndroidBlueTooth bluetoothReader = new ReaderAndroidBlueTooth();
                        final int st = bluetoothReader.openReader(bluetoothDevices);
                        if (st < 0) {
                            etResultAddStr(">>>读写器连接失败!");
                        } else {
                            reader = bluetoothReader;
                            etResultAddStr("读写器连接成功");
                            ReaderOperation();
                        }
                        pb.cancel();
                    } catch (Exception e) {
                        // TODO: handle exception
                        Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
                    }
                } else {
                    pb.cancel();
                    etResultAddStr("未扫描到蓝牙读写器。");
                }
            }
        }
    };

    //打开设备
    private class btnOpenReaderClick implements OnClickListener {

        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub

            switch (readerType) {
                case 0:
                    // 获取USB管理器
                    manager = (UsbManager) getSystemService(Context.USB_SERVICE);
                    // 获取一个已连接的USB设备，并且包含方法，以访问其标识信息、 接口和端点
                    HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
                    if (deviceList.size() == 0) {
                        etResultAddStr("未找到设备");
                        return;
                    }
                    // 获取deviceList迭代器
                    Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
                    // 判断迭代器中是否有元素
                    while (deviceIterator.hasNext()) {
                        // 如果有，获取元素
                        UsbDevice usbDevice = deviceIterator.next();

                        if (!ReaderAndroidUsb.isSupported(usbDevice)) {
                            continue;
                        }
                        // 判断是否拥有该设备的连接权限
                        if (!manager.hasPermission(usbDevice)) {
                            // 如果没有则请求权限
                            PendingIntent mPermissionIntent = PendingIntent.getBroadcast(MainActivity.this, 0,
                                    new Intent(Device_USB), PendingIntent.FLAG_UPDATE_CURRENT);
                            /*
                             * 展示征求用户同意连接这个设备的权限的对话框。 当用户回应这个对话框时,
                             * 广播接收器就会收到一个包含用一个boolean值来表示结果的EXTRA_PERMISSION_GRANTED字段的意图。
                             * 在连接设备之前检查这个字段的值是否为true和设备之间的“交流”
                             */
                            manager.requestPermission(usbDevice, mPermissionIntent);
                        } else {
                            // 如果已经拥有该设备的连接权限，直接对该设备操作
                            readerAndroidUsb = new ReaderAndroidUsb(manager);
                            try {
                                int st = readerAndroidUsb.openReader(usbDevice);
                                if (st >= 0) {
                                    reader = readerAndroidUsb;
                                    etResultAddStr("读写器连接成功");
                                    ReaderOperation();
                                } else {
                                    etResultAddStr("读写器连接失败");
                                }

                            } catch (Exception e) {
                                // TODO: handle exception
                                etResultAddStr("读写器连接出错");
                            }
                        }
                    }
                    break;
                case 1:
                    // 普通 蓝牙操作
                    BluetoothDevice();
                    break;
                case 2:
                    // BLE蓝牙操作
                    BLEBluetoothDevice();
                    break;
                case 3:
                    try {
                        // 如果Android的串口为/dev/ttyS0的话直接输入COM0
                        // String sport = spSerialPort.getSelectedItem().toString();
                        // 如果不是则要输入串口文件名,如我们测试使用的平板是/dev/s3c2410_serial
                        String sport = "/dev/s3c2410_serial" + spSerialPort.getSelectedItemId();
                        ReaderAndroidCom rac = new ReaderAndroidCom();
                        Thread.sleep(100);
                        int st = rac.openReader(sport, "115200");
                        if (st < 0) {
                            etResultAddStr(rac.getErrDescription(0, st) + st);
                            return;
                        }

                        reader = rac;
                        ReaderOperation();
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        final String str = e.getMessage();
                        Log.i(TAG, str);
                        etResultAddStr(str);
                    }
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * @param str 要添加的信息
     * @return void
     * @Description 提示信息框添加信息
     */
    private void etResultAddStr(String str) {
        result.setText(result.getText() + " " + str + "\n");
        result.setSelection(result.length());// 调整光标到最后一行
    }

    /**
     * @param device UsbDevice
     * @return void 
     * @Description 打开读写器并读取基本信息
     */
    public void ReaderOperation() {

        try {
            // reader.beep(3, 3, 3); //有些设备无此命令
            etResultAddStr("硬件版本号: " + reader.getHardwareVer());
            etResultAddStr("产品序列号：" + reader.getSerialNumber());

            spCommunicationMethod.setEnabled(false);
            rbBluetooth.setEnabled(false);
            rbBLEBluetooth.setEnabled(false);
            etBluetoothName.setEnabled(false);
        } catch (Exception e) {
            etResultAddStr(e.getMessage());
        }
    }

    //打开低功耗蓝牙
    public void BLEBluetoothDevice() {
        /*
         * if (System.currentTimeMillis() - beforeClick < 2000) {
         * Toast.makeText(MainActivity.this, "操作过于频繁,会造成操作失败,请稍后再试",
         * Toast.LENGTH_LONG).show(); return; }
         */

        // begin 判断是否支持蓝牙并获取蓝牙权限
        this.permissions = true;
        // 获取BluetoothAdapter
        BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();

        // 检查是否支持蓝牙
        if (mBluetoothAdapter == null) {
            Toast.makeText(MainActivity.this, "此设备不支持蓝牙", Toast.LENGTH_SHORT).show();
            return;
        }

        synchronized (mLockStatus) {
            try {
                // 请求打开蓝牙
                if (!mBluetoothAdapter.isEnabled()) {
                    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    startActivityForResult(enableBtIntent, REQUEST_CODE_ACCESS_5_Down);
                    mLockStatus.wait(5000);

                    if (this.permissions == false) {
                        Toast.makeText(MainActivity.this, "权限未打开", Toast.LENGTH_SHORT).show();
                        return;
                    }
                }

                // 如果 API level是大于等于23(Android6.0) 时
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    // 判断是否具有权限
                    if (ContextCompat.checkSelfPermission(this,
                            Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        // 请求权限
                        ActivityCompat.requestPermissions(this,
                                new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_CODE_ACCESS_6);
                        mLockStatus.wait(5000);
                    }

                    // 如果定位未打开，请求定位
                    if (!isLocationEnable(this)) {
                        Intent locationIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        this.startActivityForResult(locationIntent, REQUEST_CODE_LOCATION);
                    }
                    mLockStatus.wait(5000);
                }

            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        // end

        Log.i(TAG, "开始扫描！");
        mHandler.postDelayed(new Runnable() {

            @Override
            public void run() {
                // 10秒后停止扫描
                if (isScan) {
                    isScan = false;
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    pb.cancel();
                    etResultAddStr(">>>未扫描到蓝牙读写器");
                }
                // mBluetoothAdapter.stopLeScan(mLeScanCallback);
                // pb.cancel();
            }

        }, SCAN_PERIOD);
        isScan = true;
        isHaveDevice = false;
        mBluetoothAdapter.startLeScan(mLeScanCallback);
        pb.setMessage("正在搜索附近蓝牙设备。。。");
        // 设置ProgressDialog 是否可以按退回按键取消
        pb.setCancelable(false);
        pb.show();
    }

    // Device scan callback.
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {

        @Override
        public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
            String deviceName = device.getName();
            Log.w(TAG, device.getName() + ":" + device.getAddress());
            if (isHaveDevice || isScan == false) {
                return;
            }
            // 判断扫描到的蓝牙名称是否是明华C5读写器
            if (deviceName != null) {
                etResultAddStr(">>>扫描到设备: \n" + device.getName() + ":" + device.getAddress());
                if (deviceName.equals(deviceNameStr)) {
                    isHaveDevice = true;
                    isScan = false;
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    // etResultAddStr(">>>扫描到设备: \n" + device.getName() + ":" +
                    // device.getAddress());
                    try {
                        ReaderAndroidBLE rble = new ReaderAndroidBLE(MainActivity.this);
                        Thread.sleep(100);
                        rble.openReader(device);
                        reader = rble;
                        ReaderOperation();
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        final String str = e.getMessage();
                        Log.i(TAG, str);
                        etResultAddStr(str);
                    }
                    pb.cancel();
                }
            }
        }
    };

    //打开普通蓝牙
    public void BluetoothDevice() {
        // 获取本地蓝牙适配器
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null) {
            // 设备不支持蓝牙   
            System.out.println("设备不支持蓝牙");
            return;
        }
        // 打开蓝牙
        if (!mBluetoothAdapter.isEnabled()) {
            /* 不做提示，强行打开 */
            // mAdapter.enable();
            // Log.e("BlueTooth", "打开蓝牙成功");
            // 蓝牙打开会有一定的时间，在打开蓝牙后立即进行搜索会失败，所以这里提示用户先打开蓝牙再操作
            Toast.makeText(MainActivity.this, "请先打开蓝牙再操作。。。", Toast.LENGTH_LONG).show();
            return;
        }

        // 搜索蓝牙设备,在广播接收器中对蓝牙进行操作,蓝牙搜索有可能失败
        if (!mBluetoothAdapter.startDiscovery()) {
            Toast.makeText(MainActivity.this, "蓝牙搜索失败!", Toast.LENGTH_LONG).show();
            return;
        }
        // 设置进度条
        pb.setMessage("正在搜索附近蓝牙设备。。。");
        // 设置ProgressDialog 是否可以按退回按键取消
        pb.setCancelable(false);
        pb.show();
    }

    @Override
    protected void onDestroy() {
        // 在Activity结束的时候自动撤销该广播
        unregisterReceiver(mUsbReceiver);
        super.onDestroy();
    }

    /**
     * 判断定位是否打开
     *
     * @param context
     * @return location is enable if return true, otherwise disable.
     */
    public static final boolean isLocationEnable(Context context) {
        LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        boolean networkProvider = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        boolean gpsProvider = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        if (networkProvider || gpsProvider)
            return true;
        return false;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // User chose not to enable Bluetooth.
        synchronized (mLockStatus) {
            if (requestCode == REQUEST_CODE_ACCESS_5_Down) {
                if (resultCode == Activity.RESULT_CANCELED) {
                    this.permissions = false;
                    // return;
                }
            } else if (requestCode == REQUEST_CODE_LOCATION) {
                if (isLocationEnable(this)) {
                    // 定位已打开的处理
                    this.permissions = true;
                } else {
                    // 定位依然没有打开的处理
                    this.permissions = false;
                }
            }
            mLockStatus.notify();
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        synchronized (mLockStatus) {
            if (requestCode == REQUEST_CODE_ACCESS_6) {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 用户允许改权限，0表示允许，-1表示拒绝 PERMISSION_GRANTED = 0，
                    // PERMISSION_DENIED = -1
                    // permission was granted, yay! Do the contacts-related task
                    // you
                    // need to do.
                    // 这里进行授权被允许的处理
                    this.permissions = true;
                } else {
                    // permission denied, boo! Disable the functionality that
                    // depends on this permission.
                    // 这里进行权限被拒绝的处理
                    this.permissions = false;
                }
            }
            mLockStatus.notify();
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}
